#pragma once

//////////////////////////////////////////////////////////////////////////
#include <Windows.h>
#include "common/container.h"
#include "lockhelper/LockHelper.h"
#include "common/IBaseCallback.h"


//////////////////////////////////////////////////////////////////////////
template <typename T_call>
class CBase_ObserverT : public CData_BasePtrVector< T_call >
{
public:
    CBase_ObserverT()
        : CData_BasePtrVector( FALSE ){}
public:

    virtual void BaseRegisterObserver( T_call* piObserver )
    {
        if ( !piObserver )
            return ;

        CObjectLock objLocker( &m_lkObservers );
        AddItem( piObserver );
    }

    virtual void BaseUnregisterObserver( T_call* piObserver )
    {
        if ( !piObserver )
            return ;

        CObjectLock objLocker( &m_lkObservers );
        DeleteItem( piObserver );
    }

    virtual void ReleaseAll()
    {
        CObjectLock objLocker( &m_lkObservers );
        CData_BasePtrVector::ReleaseAll();
    }

    CLock	m_lkObservers;
};

//////////////////////////////////////////////////////////////////////////
class CBase_Observer : public CBase_ObserverT< IBaseCallback >
{
public:

    HRESULT CommonCallback( UINT32 u32Code, HRESULT hr, LPVOID lpUserData = NULL )
    {
        CObjectLock objLocker( &m_lkObservers );

        CData_BasePtrVector::VECTOR_DATA_TYPE_P::iterator iter_end = m_vecDatas.end();

        HRESULT hrRet = S_OK;
        for (
            CData_BasePtrVector::VECTOR_DATA_TYPE_P::iterator iter_index = m_vecDatas.begin();
            iter_index != iter_end;
        iter_index ++)
        {
            hrRet = ( *iter_index )->CommonCallback( u32Code, hr, lpUserData );
            if ( FAILED( hrRet ) )
                break;
        }

        return hrRet;
    }
};
